/*
 * @Author: your name
 * @Date: 2020-07-31 20:01:18
 * @LastEditTime: 2020-08-01 10:06:15
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /Projects/linux/Program/客服系统/list.c
 */ 
 #include "../include/common_list.h"
/*
	功能：输出错误，并且结束进程
	参数：s：出错信息字符串
	返回值：无
	作者：ljj
	时间：2020/7/31
*/
void perr_exit(const char *s){
	perror(s);
	exit(1);
}
/*
	功能：创建链表头节点
	参数：无
	返回值：链表头节点指针
	作者：ljj
	时间：2020/7/31
*/
COMMONNODE *creat_common_list(){

	COMMONNODE *head = (COMMONNODE*)malloc(sizeof(COMMONNODE));
	if (head == NULL){
		perr_exit("fail to creat common list head node");
	}
	head->next = NULL;
	
	return head;	
}

/*
	功能：根据id，和name创建节点
	参数：id：用户的id， name：用户的名字
	返回值：节点指针
	作者：ljj
	时间：2020/7/31
*/
COMMONNODE *creat_common_node_by_basic_information(const char *id, const char *name)
{
    COMMONNODE *node = (COMMONNODE *)malloc(sizeof(COMMONNODE));
	if (node == NULL){
		perr_exit("fail to creat common node");
	}
	//为id和name申请动态内存
	node->id = (char *)malloc(strlen(id) + 1); 
    node->name = (char *)malloc(strlen(name) + 1); ;
	strcpy(node->name, id);
    strcpy(node->name, name);;

    node->next = NULL;

    return node;
}
/*
	功能：增加链表节点，链接上传入的node
	参数：head：链表头指针， node:节点指针
	返回值：无
	作者：ljj
	时间：2020/7/31
*/
void add_common_node(COMMONNODE *head, COMMONNODE *node){
	
    if (head == NULL){
		perr_exit("head is NULL");
    }
    COMMONNODE *index = head;
	//找到链表尾部
    while (index->next != NULL){
        index = index->next;
    }

    index->next = node;
}
/*
	功能：根据用户id账号查找节点
	参数：head：链表头指针， id:用户id账号
	返回值：查找到的节点指针
	作者：ljj
	时间：2020/7/31
*/
COMMONNODE *find_common_node_by_id(COMMONNODE *head, const char *id)
{
    if (head == NULL){
        perr_exit("head is NULL");
    }

    COMMONNODE *index = head->next;

    while (index != NULL){
        if (strcmp(index->id, id) != 0){
            index = index->next;
        } else {
            return index;
        }
    }
    return NULL;
}
/*
	功能：根据用户名查找节点
	参数：head：链表头指针， name:用户名
	返回值：查找到的节点指针
	作者：ljj
	时间：2020/7/31
*/
COMMONNODE *find_common_node_by_name(COMMONNODE *head, const char *name)
{
    if (head == NULL){
        perr_exit("head is NULL");
    }

    COMMONNODE *index = head->next;

    while (index != NULL){
        if (strcmp(index->name, name) != 0){
            index = index->next;
        } else {
            return index;
        }
    }
    return NULL;
}
/*
	功能：删除节点,释放malloc出来的内存
	参数：node：二级节点指针
	返回值：无
	作者：ljj
	时间：2020/7/31
*/
void del_common_node(COMMONNODE **node)
{
    (*node)->next = NULL;
	//释放id占用的动态内存
    if ((*node)->id != NULL){
        free((*node)->id);
        (*node)->id = NULL;
    }
	//释放name占用的动态内存
    if ((*node)->name != NULL){
        free((*node)->name);
        (*node)->name = NULL;
    }
	//释放node指针占用的内存
    free(*node);
    *node = NULL;
}
/*
	功能：根据id账号删除节点
	参数：head：链表头指针， id:用户id账号
	返回值：-1：删除失败   0:删除成功
	作者：ljj
	时间：2020/7/31
*/
int del_common_node_by_id(COMMONNODE *head, const char *id)
{
    if (head == NULL){
        perr_exit("head is NULL");
    }
	//双指针
    COMMONNODE *index = head->next;
    COMMONNODE *index2 = head;
    while (index != NULL){
        if (strcmp(index->id, id) == 0){
            break;
        } else {
            index2 = index;
            index = index->next;
        }
    }
	//找不到要删除的节点
    if (index == NULL){
        return -1;
    }
    index2->next = index->next;
    del_common_node(&index);
	return 0;
}
/*
	功能：清空链表，删除所有节点
	参数：head：链表头指针
	返回值：无
	作者：ljj
	时间：2020/7/31
*/
void clear_common_list(COMMONNODE *head)
{
    if (head == NULL){
        perr_exit("head is NULL");
    }
    COMMONNODE *index = head->next;
    while (index != NULL){
        head->next = index->next;
        del_common_node(&index);
        index = head->next;
    }
}
/*
	功能：摧毁链表
	参数：head：链表头指针
	返回值：无
	作者：ljj
	时间：2020/7/31
*/
void destory_common_list(COMMONNODE **head)
{
    clear_common_list(*head);
    free(*head);
    *head = NULL;
}

/*
	功能：打印节点信息id 和 name
	参数：node:节点指针
	返回值：无
	作者：ljj
	时间：2020/7/31
*/
void display_common_basic_information(COMMONNODE *node)
{
    if (node == NULL){
        perr_exit("node is NULL");
    }
    printf("\t\t%s\t%s ", node->id, node->name);
}

/*
	功能：打印全部节点信息id 和 name
	参数：head:头节点指针
	返回值：无
	作者：ljj
	时间：2020/7/31
*/
void display_common_all_basic_information(COMMONNODE *head)
{
    if (head == NULL){
        perr_exit("head is NULL");
    }
    COMMONNODE *index = head->next;
	//遍历链表打印id和name
    while (index != NULL){
       display_common_basic_information(index);
       printf("\n");
       index = index->next;
    }
}

/*
	功能：在对应身份的文件夹的id账号文件中保存链表  
	参数：identity:用户身份  head 链表的头指针
	返回值：0：保存成功  -1：保存失败
	作者：ljj
	时间：2020/7/31
*/
int save_common_List(const char *identity, COMMONNODE *head){

	char FilePath[128] = {'\0'};
	strcat(FilePath, "../");
	strcat(FilePath, identity);
	strcat(FilePath, "/id.txt");
	//可写的方式打开id文件
	FILE *fp = fopen(FilePath, "w");
	if (fp == NULL || head == NULL) {
		return -1;
	}
	COMMONNODE *p = head;
	//将链表里的数据保存到文件
	while (p->next != NULL) {
		p = p->next;
		fprintf(fp, "%s %s\n", p->id, p->name);
	}
	fclose(fp);
	return 0;
}		
/*
	功能：按身份在对应文件夹内的id文件中读取内容，并返回一个链表    
	参数：identity 身份  
	返回值： 生成的链表头指针  
	作者：ljj
	时间：2020/7/31
*/
COMMONNODE* load_common_List(const char *identity){

	char FilePath[128] = {'\0'};
	//字符串拼接文件路径
	strcat(FilePath, "../");
	strcat(FilePath, identity);
	strcat(FilePath, "/id.txt");
	//可读的方式打开id
	FILE *fp = fopen(FilePath, "r");
	if (fp == NULL) {
		 perr_exit("id.txt may not exist");
	}
	COMMONNODE *head = creat_common_list();
	COMMONNODE *node;
	char buf[128] = {'\0'};
	char id[64] = {'\0'};
	char name[64] = {'\0'};
	//将文件里的id和name读出，生成链表
	while (fgets(buf, sizeof(buf), fp) != NULL) {
		sscanf(buf, "%s %s", id, name);
		node = creat_common_node_by_basic_information(id, name);
		add_common_node(head, node);
	}
	
	fclose(fp);
	return head;
}	


